﻿using System;
using Nop.Services.Logging;
using Nop.Services.Tasks;
using Nop.Core.Caching;

namespace Nop.Services.Messages
{
    /// <summary>
    /// Represents a task for sending queued message 
    /// </summary>
    public partial class QueuedMessagesSendTask : ITask
    {
        private readonly IQueuedEmailService _queuedEmailService;
        private readonly IEmailSender _emailSender;
        private readonly ILogger _logger;
		private readonly IRemoteLockProvider _distributedLockProvider;

        public QueuedMessagesSendTask(IQueuedEmailService queuedEmailService,
			IEmailSender emailSender, ILogger logger, IRemoteLockProvider distributedLockProvider)
        {
			this._distributedLockProvider = distributedLockProvider;
            this._queuedEmailService = queuedEmailService;
            this._emailSender = emailSender;
            this._logger = logger;
        }

        /// <summary>
        /// Executes a task
        /// </summary>
        public void Execute()
        {
			_distributedLockProvider.AcquireLockAndExecute("SendingEmail", 60, () => {
				var maxTries = 3;
				var queuedEmails = _queuedEmailService.SearchEmails(null, null, null, null,
					true, maxTries, false, 0, 100);
				foreach (var queuedEmail in queuedEmails)
				{
					var bcc = String.IsNullOrWhiteSpace(queuedEmail.Bcc)
								? null
								: queuedEmail.Bcc.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
					var cc = String.IsNullOrWhiteSpace(queuedEmail.CC)
								? null
								: queuedEmail.CC.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

					try
					{
						_emailSender.SendEmail(queuedEmail.EmailAccount, queuedEmail.Subject, queuedEmail.Body,
						   queuedEmail.From, queuedEmail.FromName, queuedEmail.To, queuedEmail.ToName, bcc, cc);

						queuedEmail.SentOnUtc = DateTime.UtcNow;
					}
					catch (Exception exc)
					{
						_logger.Error(string.Format("Error sending e-mail. {0}", exc.Message), exc);
					}
					finally
					{
						queuedEmail.SentTries = queuedEmail.SentTries + 1;
						_queuedEmailService.UpdateQueuedEmail(queuedEmail);
					}
				}
			});           
        }
    }
}
